package com.play.ballen.home.ui

import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.PowerManager
import android.provider.Settings
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.RecyclerView
import com.hjq.toast.ToastUtils
import com.play.ballen.R
import com.play.ballen.databinding.FragmentHomeBinding
import com.play.ballen.home.adapter.MyBannerAdapter
import com.play.ballen.home.dialog.PayDialogUtils
import com.play.ballen.home.entity.HomeBallInfo
import com.play.ballen.home.entity.HomeBannerInfo
import com.play.ballen.home.task.TaskUtil
import com.play.ballen.home.vm.HomeFragmentVM
import com.play.ballen.utils.PhoneTools
import com.tbruyelle.rxpermissions2.RxPermissions
import com.yuven.appframework.util.addToDisposable
import com.yuven.appframework.util.imageloader.ImageUtil
import com.yuven.appframework.util.setOnSingleClickListener
import com.yuven.appframework.widget.banner.indicator.CircleIndicator
import com.yuven.baselib.component.BaseMVVMFragment
import com.yuven.baselib.utils.Logger
import com.yuven.baselib.utils.ResourceUtil
import com.yuven.baselib.utils.ViewUtils
import com.yuven.baselib.widget.MultiStateView

class HomeFragment : BaseMVVMFragment<HomeFragmentVM, FragmentHomeBinding>() {

    private var isLoadData = false

    private var curBallIndex = 0

    private val payDialogUtils by lazy {
        PayDialogUtils(mContext).apply {
            valuesCallback = {
                viewModel.gasSubmit()
            }
        }
    }

    var startRegisterStepSensor: (() -> Unit)? = null
    var stepSensorAvailable: (() -> Boolean)? = null

    companion object {
        val TAG: String = HomeFragment::class.java.simpleName

        const val REQ_CODE_BATTERY = 1000

        fun newInstance(): HomeFragment {
            return HomeFragment()
        }
    }

    override fun initIntent() {}

    override fun layoutId(): Int {
        return R.layout.fragment_home
    }

    override fun viewModelClass(): Class<HomeFragmentVM> {
        return HomeFragmentVM::class.java
    }

    override fun initView() {
//        MapsInitializer.updatePrivacyShow(context, true, true)
//        MapsInitializer.updatePrivacyAgree(context, true)
        dataBinding.fakeStatusBar.layoutParams.height = ViewUtils.getStatusHeight()

        dataBinding.msvLayout.findViewById<Button>(R.id.btnTryAgain).setOnClickListener {
            dataBinding.msvLayout.viewState = MultiStateView.VIEW_STATE_LOADING
            viewModel.index()
        }

        dataBinding.imgMessage.setOnSingleClickListener {
            ServiceActivity.start(mContext)
        }

        dataBinding.tvNotice.setOnSingleClickListener {
            NoticeListActivity.start(mContext)
        }

        dataBinding.btnStart.setOnSingleClickListener {
            isIgnoreBatteryOptimizations()
        }

        dataBinding.imgSwitchBall.setOnClickListener {
            viewModel.homeIndexInfo.value?.run {
                list?.run {
                    if (this.size == 1) {
                        return@run
                    }

                    if (curBallIndex < this.size - 1) {
                        curBallIndex++
                    } else {
                        curBallIndex = 0
                    }
                    setBallView(this[curBallIndex])
                }
            }
        }
    }

    override fun initData() {
        dataBinding.refreshLayout.setEnableLoadMore(false)
        dataBinding.refreshLayout.setOnRefreshListener {
            viewModel.index()
        }
        viewModel.getVersion(PhoneTools.getVersionCode(context).toString())
    }

    override fun initObserver() {
        super.initObserver()
        //版本
        viewModel.version.observe(this) {
            if (it.version.toInt()> PhoneTools.getVersionCode(context)) {
                DiaLogActivity.start(context,it)
            }
        }
        viewModel.actionIndexFail.observe(this) {
            dataBinding.refreshLayout.finishRefresh()
            dataBinding.msvLayout.viewState = MultiStateView.VIEW_STATE_ERROR
        }

        viewModel.homeIndexInfo.observe(this) {
            dataBinding.refreshLayout.finishRefresh()
            if (it == null) {
                dataBinding.msvLayout.viewState = MultiStateView.VIEW_STATE_EMPTY
                return@observe
            }
            //banner
            if (!it.banner.isNullOrEmpty()) {
                dataBinding.cslBanner.visibility = View.VISIBLE
                setBannerView(it.banner)
            } else {
                dataBinding.cslBanner.visibility = View.GONE
            }

            //公告
            if (!it.notic.isNullOrEmpty()) {
                dataBinding.tvNotice.visibility = View.VISIBLE
                setNoticeView(it.notic)
            } else {
                dataBinding.tvNotice.visibility = View.GONE
            }

            if (!it.list.isNullOrEmpty()) {
                curBallIndex = 0
                setBallView(it.list[curBallIndex])
            }

            dataBinding.msvLayout.viewState = MultiStateView.VIEW_STATE_CONTENT
        }

        viewModel.playCountInfo.observe(this) {
            it?.let {
                TaskUtil.setPlayCountInfo(it)
                startRegisterStepSensor?.invoke()

                ToastUtils.show(ResourceUtil.getString(R.string.play_count_submit_tip))
                PlayCountActivity.start(mContext)
            }
        }
        viewModel.gasInfo.observe(this) {
            it?.run {
                payDialogUtils.show(price, period)
            }
        }
    }

    override fun onResume() {
        super.onResume()
        if (!isLoadData) {
            dataBinding.msvLayout.viewState = MultiStateView.VIEW_STATE_LOADING
            viewModel.index()
            isLoadData = true
        } else {
            if (dataBinding.banner.itemCount > 1) {
                dataBinding.banner.start()
            }
            dataBinding.tvNotice.startToNext()
        }
    }

    override fun onPause() {
        super.onPause()
        if (dataBinding.banner.itemCount > 1) {
            dataBinding.banner.stop()
        }
        dataBinding.tvNotice.stop()
    }

    private fun setBannerView(bannerList: List<HomeBannerInfo>) {
        dataBinding.banner.setAdapter(MyBannerAdapter(bannerList))
        dataBinding.banner.indicator = CircleIndicator(mContext)
        //mBanner.addBannerLifecycleObserver(this)

        val recyclerView = dataBinding.banner.viewPager2.getChildAt(0) as RecyclerView

        //宽高比例690:250
        val ratio = 690f / 250f
        val widthUI = ViewUtils.getScreenWidth() - ViewUtils.dip2px(15f * 2)    //左右各15dp间距
        val heightUI = (widthUI / ratio).toInt()
        Logger.i(TAG, "setBannerView widthUI = $widthUI, heightUI = $heightUI")

        //宽度可以沾满 RecyclerView有paddingLeft=15dp 子item有marginRight=15dp 所以最终宽高比例是正确的
        recyclerView.layoutParams =
            ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, heightUI)
        //设置viewPager2 padding穿透效果
        recyclerView.setPadding(ViewUtils.dip2px(15f), 0, 0, 0)
        recyclerView.clipToPadding = false

        dataBinding.banner.setOnBannerListener { data, position ->
            Logger.i(TAG, "banner listener position $position")
            (data as? HomeBannerInfo)?.run {
                if (content.isNullOrBlank()) {
                    return@run
                }
                if (!content.startsWith("http://") && !content.startsWith("https://")) {
                    return@run
                }
                try {
                    val intent = Intent()
                    intent.action = Intent.ACTION_VIEW
                    intent.data = Uri.parse(content)
                    startActivity(
                        Intent.createChooser(
                            intent,
                            ResourceUtil.getString(R.string.browser_select_tip)
                        )
                    )
                } catch (e: Exception) {
                    e.printStackTrace()
                    ToastUtils.show(ResourceUtil.getString(R.string.browser_select_error))
                }
            }
        }
    }

    private fun setNoticeView(noticeList: List<HomeBannerInfo>) {
        val arrayList = arrayListOf<String>()
        noticeList.forEach {
            arrayList.add(it.title)
        }
        dataBinding.tvNotice.setHotKeyList(arrayList)
        dataBinding.tvNotice.startToNext()
    }

    private fun setBallView(info: HomeBallInfo) {
        info.run {
            ImageUtil.instance.loadImage(0, 0, pic, dataBinding.imgBall)

            dataBinding.tvPropertyNo.text =
                ResourceUtil.getString(R.string.home_property_no_text, no)
            dataBinding.tvPropertyLevel.text = name
            dataBinding.tvPropertySport.text = "$percent%"
            dataBinding.tvPropertyDate.text = if (name!= "0") {
                ResourceUtil.getString(R.string.home_property_date_forever)
            } else {
                ResourceUtil.getString(R.string.twenty_end)
            }
            dataBinding.tvPropertyPlayCount.text =
                ResourceUtil.getString(R.string.home_property_play_count_text, task_count)
            dataBinding.tvPropertyPrice.text =
                ResourceUtil.getString(R.string.home_property_price_text, price)
        }
    }

    private fun isIgnoreBatteryOptimizations() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val powerManager = mContext.getSystemService(Context.POWER_SERVICE) as PowerManager?
            val hasIgnore =
                powerManager?.isIgnoringBatteryOptimizations(mContext.packageName) ?: false
            Logger.i("HomeFragment powerManager hasIgnore = $hasIgnore")
            if (!hasIgnore) {
                val builder = AlertDialog.Builder(mContext)
                builder.setTitle(ResourceUtil.getString(R.string.step_dialog_title))
                builder.setMessage(ResourceUtil.getString(R.string.step_dialog_content))
                builder.setCancelable(false)
                builder.setNegativeButton(ResourceUtil.getString(R.string.step_dialog_cancel_text),
                    DialogInterface.OnClickListener { dialog, which ->
                        ToastUtils.show(ResourceUtil.getString(R.string.step_ignore_battery_optimizations_tip))
                    })
                builder.setPositiveButton(ResourceUtil.getString(R.string.step_dialog_ok_text),
                    DialogInterface.OnClickListener { dialog, which ->
                        try {
                            val intent =
                                Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
                            intent.data = Uri.parse("package:${mContext.packageName}")
                            //启动忽略电池优化，会弹出一个系统的弹框，我们在上面的
                            startActivityForResult(intent, REQ_CODE_BATTERY)
                        } catch (e: Exception) {
                            e.printStackTrace()
                        }
                    })
                builder.show()
            } else {
                readyToTask()
            }
        } else {
            readyToTask()
        }
    }

    private fun readyToTask() {
        if (!mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_COUNTER)) {
            Logger.i("HomeFragment step counter is NOT supported")
            ToastUtils.show(ResourceUtil.getString(R.string.step_sensor_not_support))
            return
        }

        val sensorAvailable = stepSensorAvailable?.invoke() ?: false
        if (!sensorAvailable) {
            Logger.i("HomeFragment step counter sensor not available")
            ToastUtils.show(ResourceUtil.getString(R.string.step_sensor_not_available))
            return
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            RxPermissions(mActivity)
                .request(Manifest.permission.ACTIVITY_RECOGNITION)
                .subscribe({ granted ->
                    if (granted) {
                        viewModel.task()
                    } else {
                        ToastUtils.show(ResourceUtil.getString(R.string.step_permission_denied))
                    }
                }, { throwable ->
                    Logger.i("request permission error throws message:${throwable.message}")
                }).addToDisposable(mCompositeDisposable)
        } else {
            viewModel.task()
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQ_CODE_BATTERY) {
            if (resultCode == Activity.RESULT_OK) {
                Logger.i("onActivityResult battery result ok")
                readyToTask()
            } else {
                Logger.i("onActivityResult battery result cancel")
                ToastUtils.show(ResourceUtil.getString(R.string.step_ignore_battery_optimizations_tip))
            }
        }
    }
}